#ifndef __RSC_ENCODER_H
#define __RSC_ENCODER_H 1

//#include<iostream.h>
//#include<fstream.h>
#include<limits.h>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>

class rsc_encoder
{
	private:

	unsigned int N,K,M,*** G,** h,** z,*** H,*** Z;
	unsigned int initial_state,present_state,next_state;
	unsigned int *shift_register_length,encoder_memory,state_number,k_number,n_number;
	unsigned int *U,*V,**STATE,**D,**D1,**information;
	unsigned int ** WEIGHT_SIZE,** WEIGHT_SIZE_1;
	double ***WEIGHT_ENUMERATOR,***WEIGHT_ENUMERATOR_1;

	unsigned int ZEROTAIL_SIZE;
   unsigned int * RIM,* RIMa,* RIMb,* RIMc,* RIMd,* RIMe; // Random Interleaving;
   unsigned int * zerotail_bits;

	public:

	rsc_encoder(unsigned int _N,unsigned int _K,unsigned int _M,unsigned int *** _G,unsigned int _ZEROTAIL_SIZE);
	~rsc_encoder();

	unsigned int get_k(void) { return K; };
	unsigned int get_n(void) { return N; };
	unsigned int get_m(void) { return M; };
	unsigned int get_k_number(void) { return k_number; };
   unsigned int get_n_number(void) { return n_number; };
	unsigned int get_state_number(void) { return state_number; };
	unsigned int get_zerotail_size(void) { return ZEROTAIL_SIZE; };
	unsigned int * get_zerotail_bits(void) { return zerotail_bits; };

	unsigned int ** get_D(void)
	{
	  unsigned int i,j;

	  unsigned int ** copysequence=new unsigned int * [state_number];
	  for(i=0;i<state_number;i++) copysequence[i]=new unsigned int [k_number];

	  for(i=0;i<state_number;i++)
		for(j=0;j<k_number;j++) copysequence[i][j]=D[i][j];

	  return copysequence;
	};


	unsigned int ** get_D1(void)
	{
	  unsigned int i,j;

	  unsigned int ** copysequence=new unsigned int * [state_number];
	  for(i=0;i<state_number;i++) copysequence[i]=new unsigned int [k_number];

	  for(i=0;i<state_number;i++)
		for(j=0;j<k_number;j++) copysequence[i][j]=D1[i][j];

	  return copysequence;
	};


   unsigned int * systematic_convolutional_encoder(unsigned int * _U);

   unsigned int * get_zerotail_sequence(unsigned int * _U);
   unsigned int * get_tailbiting_sequence(unsigned int * _U);

   unsigned int * get_zerotail_sequence_livro(unsigned int * _U);

   unsigned int * generate_transmitted_sequence(unsigned int * X,unsigned int * Y1,unsigned int * Y2);
   long double * received_sequence_decoder_1(long double * R);
   long double * received_sequence_decoder_2(long double * R);

   long double * add_extrinsic_information(long double * A,long double * B);



   unsigned int * random_interleaving_i(unsigned int * input_sequence,unsigned int index);
   unsigned int * random_deinterleaving_i(unsigned int * input_sequence,unsigned int index);

   long double * random_interleaving_2_i(long double * input_sequence,unsigned int index);
   long double * random_deinterleaving_2_i(long double * input_sequence,unsigned int index);

   unsigned int * random_interleaving(unsigned int * input_sequence);	   // -------> 3GPP
   unsigned int * random_deinterleaving(unsigned int * input_sequence);		// -------> 3GPP

   long double * random_interleaving_2(long double * input_sequence);		// -------> 3GPP
   long double * random_deinterleaving_2(long double * input_sequence);		// -------> 3GPP

	void reset_encoder_state(void);

   void rsc_set_state(unsigned int s);
   unsigned int rsc_get_state(void);

   void rsc_generate_state_diagram(void);
   void rsc_generate_state_diagram_1(void);

	unsigned int * convert_decimal_binary(unsigned int decimal,unsigned int size);
	unsigned int convert_binary_decimal(unsigned int * binary,unsigned int size);

	unsigned int ** get_weight_size(void);
	long double *** get_weight_enumerator(void);
	unsigned int ** get_weight_size_1(void);
	double *** get_weight_enumerator_1(void);

};


#endif






